package service

import (
	"context"
	"fmt"
	"strings"

	"database/sql"

	dbmodel "gitee.com/hp-huiw/family-expense-api/internal/db/model"
	"gitee.com/hp-huiw/family-expense-api/internal/dto"
	"gitee.com/hp-huiw/family-expense-api/internal/repository"
	"gitee.com/hp-huiw/my-go-core/config"
	"gitee.com/hp-huiw/my-go-core/util"
	"github.com/samber/lo"
)

type RegionService interface {
	Initialize(ctx context.Context) error
	GetFlagUrl(name string) string
	Query(ctx context.Context) ([]dto.RegionResponse, error)
}

func NewRegionService(db *sql.DB) RegionService {
	return &regionService{
		db:               db,
		regionRepository: repository.NewRegionRepository(db),
	}
}

// Prepares the initial data for region.
func (s *regionService) Initialize(ctx context.Context) error {
	exists, err := s.regionRepository.Exists(ctx)

	if err != nil {
		return err
	}

	if !exists {
		models := []dbmodel.Region{
			{
				ID:    util.GenerateUUIDWithoutDashes(),
				Title: "柬埔寨",
				Name:  "cambodia",
			},
			{
				ID:    util.GenerateUUIDWithoutDashes(),
				Title: "马来西亚",
				Name:  "malaysian",
			},
			{
				ID:    util.GenerateUUIDWithoutDashes(),
				Title: "新加坡",
				Name:  "singapore",
			},
			{
				ID:    util.GenerateUUIDWithoutDashes(),
				Title: "泰国",
				Name:  "thailand",
			},
		}

		err = s.regionRepository.BatchInsert(ctx, models)
	}

	return err
}

// Gets region flag url based on its name.
func (*regionService) GetFlagUrl(name string) string {
	config := config.ConfigLoader.GetAppConfig()

	if !util.IsEmptyString(name) {
		return fmt.Sprintf("%v%v/%v.png", config.Resource.HttpBaseUrl, config.Resource.RegionFlagUrl, strings.ToLower(name))
	}

	return ""
}

// Queries all regions.
func (s *regionService) Query(ctx context.Context) ([]dto.RegionResponse, error) {
	query, err := s.regionRepository.Query(ctx)

	if err != nil {
		return nil, err
	}

	result := lo.Map(query, func(item repository.Region, _ int) dto.RegionResponse {
		return dto.RegionResponse{
			ID:      item.ID,
			Title:   item.Title,
			FlagUrl: s.GetFlagUrl(item.Name),
		}
	})

	return result, nil
}

// Container of RegionService functions.
type regionService struct {
	db               *sql.DB
	regionRepository repository.RegionRepository
}
